require 'rubygems'
require 'fox16'

require 'JournalXMLib.rb'
require 'uploader.rb'

include Fox

class JournalWindow < FXMainWindow

  include Responder
  
  journal = Journal
  
  def initialize(app)

    super(app, "Journal Viewer", :opts => DECOR_ALL, :width => 850, :height => 600)

    menubar = FXMenuBar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)

    statusbar = FXStatusBar.new(self, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|STATUSBAR_WITH_DRAGCORNER)

    topDockSite = FXDockSite.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
    FXDockSite.new(self, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X)
    FXDockSite.new(self, LAYOUT_SIDE_LEFT|LAYOUT_FILL_Y)
    FXDockSite.new(self, LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y)

    splitter = FXSplitter.new(self, (LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y| SPLITTER_TRACKING|SPLITTER_VERTICAL|SPLITTER_REVERSED))

    filemenu = FXMenuPane.new(self)
    FXMenuTitle.new(menubar, "&File", nil, filemenu)
	FXMenuCommand.new(filemenu, "&Open...\tCtl-O\tOpen image file.").connect(SEL_COMMAND, method(:onCmdOpen))
    FXMenuCommand.new(filemenu, "&Save...\tCtl-S\tSave image file.").connect(SEL_COMMAND, method(:onCmdSave))
	FXMenuCommand.new(filemenu, "&Upload...\tCtl-U\tUpload journal to flickr.").connect(SEL_COMMAND, method(:onCmdUpdate))
    FXMenuCommand.new(filemenu, "&Quit\tCtl-Q").connect(SEL_COMMAND, method(:onCmdQuit))

    imagebox = FXHorizontalFrame.new(splitter,
      FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y,
      :padLeft => 0, :padRight => 0, :padTop => 0, :padBottom => 0)
    
    @commentBox = FXLabel.new(imagebox, "", nil, LAYOUT_SIDE_TOP | JUSTIFY_LEFT)
	
    @imageview = FXImageView.new(imagebox, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
    
	
	@filebox = FXHorizontalFrame.new(splitter,
      LAYOUT_FILL_X|LAYOUT_FILL_Y,
      :padLeft => 0, :padRight => 0, :padTop => 0, :padBottom => 0)
	
    fileframe = FXVerticalFrame.new(@filebox,
      FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y,
      :padLeft => 0, :padRight => 0, :padTop => 0, :padBottom => 0, :hSpacing => 0, :vSpacing => 0)
	
    @header1 = FXHeader.new(fileframe, 
      :opts => HEADER_BUTTON|HEADER_RESIZE|FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X)
    @header1.connect(SEL_CHANGED) do |sender, sel, which|
      @lists[which].width = @header1.getItemSize(which)
    end
    @header1.connect(SEL_COMMAND) do |sender, sel, which|
      @lists[which].numItems.times do |i|
        @lists[which].selectItem(i)
      end
    end
  
    @header1.appendItem("Trip Name", nil, 150)
    @header1.appendItem("Destination", nil, 150)
    @header1.appendItem("Country", nil, 150)
	@header1.appendItem("City", nil, 150)
    @header1.appendItem("Dates", nil, 91)
    @header1.appendItem("Photos", nil, 147)
 
    panes = FXHorizontalFrame.new(fileframe, FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|LAYOUT_FILL_Y,
      :padLeft => 0, :padRight => 0, :padTop => 0, :padBottom => 0,
      :hSpacing => 0, :vSpacing => 0)

    @lists = []
    @lists.push(FXList.new(panes, :opts => LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH|LIST_SINGLESELECT, :width => 150))
    @lists.push(FXList.new(panes, :opts => LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH|LIST_SINGLESELECT, :width => 150))
    @lists.push(FXList.new(panes, :opts => LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH|LIST_SINGLESELECT, :width => 150))
    @lists.push(FXList.new(panes, :opts => LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH|LIST_SINGLESELECT, :width => 150))
    @lists.push(FXList.new(panes, :opts => LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH|LIST_SINGLESELECT, :width => 91))
    @lists.push(FXList.new(panes, :opts => LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH|LIST_SINGLESELECT, :width => 147))

	@lists[0].connect(SEL_COMMAND, method(:onCmdSel))
	@lists[1].connect(SEL_COMMAND, method(:onCmdSel))
	@lists[2].connect(SEL_COMMAND, method(:onCmdSel))
	@lists[3].connect(SEL_COMMAND, method(:onCmdSel))
	@lists[4].connect(SEL_COMMAND, method(:onCmdSel))
	@lists[5].connect(SEL_COMMAND, method(:onCmdSel))
	
    @lists[0].backColor = FXRGB(240, 240, 255)
    @lists[1].backColor = FXRGB(240, 255, 240)
    @lists[2].backColor = FXRGB(240, 240, 255)
	@lists[3].backColor = FXRGB(240, 255, 240)
    @lists[4].backColor = FXRGB(240, 240, 255)
	@lists[5].backColor = FXRGB(255, 240, 240)

    @lists[0].appendItem("All")
	@lists[1].appendItem("All")
	@lists[2].appendItem("All")
	@lists[3].appendItem("All")	
	@lists[4].appendItem("All")
	@lists[5].appendItem("None")
     
    @filename = "untitled"
    @preferredFileFilter = 0
	
  end
  
  def loadJournal(filename)
	@journal = Journal.new(filename)
	setLists()	
  end
  
  def setLists()
  		
	trips = Array.new()
	destins = Array.new()
	countries = Array.new()
	cities = Array.new()
	dates = Array.new()
	photos = Array.new()
	
	selInds = Array.new()
	selInds.push(@lists[0].currentItem())
	selInds.push(@lists[1].currentItem())
	selInds.push(@lists[2].currentItem())
	selInds.push(@lists[3].currentItem())
	selInds.push(@lists[4].currentItem())
	selInds.push(@lists[5].currentItem())	
	
	if (selInds[0] == 0)
		@journal.trips.each do |trip|
			tripIsIn = false
			trips.each do |name|
				if (name == trip.getName())
					tripIsIn = true
				end
			end
			
			if !tripIsIn  && trip.getName().size() > 1
				trips.push(trip.getName())
			end
		end
	else
		gotOne = false
		@journal.trips.each do |trip|
			if (@lists[0].getItem(selInds[0]).text == trip.getName()) 
				trips.push(trip.getName())
				selInds[0] = 1
				gotOne = true
				break
			end
		end
		if !gotOne
			selInds[0] = 0
		end
	end
	
	if (selInds[1] == 0)
		@journal.trips.each do |trip|
			trips.each do |name|
				if (name == trip.getName())
					trip.destinations.each do |destin|
						destIsIn = false
						destins.each do |name|
							if (name == destin.getName())
								destIsIn = true
							end
						end
						if !destIsIn && destin.getName().size() > 1
							destins.push(destin.getName())
						end
					end
				end
			end			
		end
	else
		gotOne = false
		@journal.trips.each do |trip|
			trips.each do |name|
				if (name == trip.getName())
					trip.destinations.each do |destin|
						destIsIn = false
						destins.each do |name|
							if (name == destin.getName())
								destIsIn = true
							end
						end
						if !destIsIn && (@lists[1].getItem(selInds[1]).text == destin.getName()) 
							destins.push(destin.getName())
							selInds[1] = 1
							gotOne = true
						end
					end
				end
			end
		end
		if !gotOne
			selInds[1] = 0
		end
	end
	
	if (selInds[2] == 0)
		@journal.trips.each do |trip|
			trips.each do |name|
				if (name == trip.getName())
					trip.destinations.each do |destin|
						destins.each do |name|
							if (name == destin.getName() )
								countIsIn = false
								countries.each do |country|
									if (country == destin.getCountry())
										countIsIn = true
									end
								end
								if !countIsIn && destin.getCountry().size() > 1
									countries.push(destin.getCountry())
								end
							end
						end
					end
				end
			end			
		end
	else
		gotOne = false
		@journal.trips.each do |trip|
			trips.each do |name|
				if (name == trip.getName())
					trip.destinations.each do |destin|
						destins.each do |name|
							if (name == destin.getName() )
								countIsIn = false
								countries.each do |country|
									if (country == destin.getCountry())
										countIsIn = true
									end
								end
								if !countIsIn && (@lists[2].getItem(selInds[2]).text == destin.getCountry())
									countries.push(destin.getCountry())
									selInds[2] = 1
									gotOne = true
								end
							end
						end
					end
				end
			end			
		end
		if !gotOne
			selInds[2] = 0
		end
	end
	
	if (selInds[3] == 0)
		@journal.trips.each do |trip|
			trips.each do |name|
				if (name == trip.getName())
					trip.destinations.each do |destin|
						destins.each do |name|
							if (name == destin.getName() )
								countries.each do |country|
									if (country == destin.getCountry())
										cityIsIn = false
										cities.each do |city|
											if (city == destin.getCity())
												cityIsIn = true
											end
										end
										if !cityIsIn &&  destin.getCity().size() > 1
											cities.push(destin.getCity())
										end										
									end
								end
							end
						end
					end
				end
			end			
		end
	else
		gotOne = false
		@journal.trips.each do |trip|
			trips.each do |name|
				if (name == trip.getName())
					trip.destinations.each do |destin|
						destins.each do |name|
							if (name == destin.getName())
								countries.each do |country|
									if (country == destin.getCountry())
										cityIsIn = false
										cities.each do |city|
											if (city == destin.getCity())
												cityIsIn = true
											end
										end
										if !cityIsIn && (@lists[3].getItem(selInds[3]).text == destin.getCity())
											cities.push(destin.getCity())
											selInds[3] = 1
											gotOne = true
										end										
									end
								end
							end
						end
					end
				end
			end			
		end
		if !gotOne
			selInds[3] = 0
		end
	end
	
	if (selInds[4] == 0)
		@journal.trips.each do |trip|
			trips.each do |name|
				if (name == trip.getName())
					trip.destinations.each do |destin|
						destins.each do |name|
							if (name == destin.getName() )
								countries.each do |country|
									if (country == destin.getCountry() )
										cities.each do |city|
											if (city == destin.getCity())
												destin.photos.each do |photo|
													dateIsIn = false
													dates.each do |date|
														if (date == photo.getDateTaken())
															dateIsIn = true
														end
													end
													if !dateIsIn  && photo.getDateTaken().size() > 1
														dates.push(photo.getDateTaken())
													end
												end
											end
										end
									end
								end
							end
						end
					end
				end
			end			
		end
	else
		gotOne = false
		@journal.trips.each do |trip|
			trips.each do |name|
				if (name == trip.getName())
					trip.destinations.each do |destin|
						destins.each do |name|
							if (name == destin.getName() )
								countries.each do |country|
									if (country == destin.getCountry() )
										cities.each do |city|
											if (city == destin.getCity() )
												destin.photos.each do |photo|
													dateIsIn = false
													dates.each do |date|
														if (date == photo.getDateTaken())
															dateIsIn = true
														end
													end
													if !dateIsIn  && (@lists[4].getItem(selInds[4]).text == photo.getDateTaken())
														dates.push(photo.getDateTaken())
														selInds[4] = 1
														gotOne = true
													end
												end
											end
										end									
									end
								end
							end
						end
					end
				end
			end			
		end
		if !gotOne
			selInds[4] = 0
		end
	end
	
	@journal.trips.each do |trip|
		trips.each do |name|
			if (name == trip.getName())
				trip.destinations.each do |destin|
					destins.each do |name|
						if (name == destin.getName() )
							countries.each do |country|
								if (country == destin.getCountry() )
									cities.each do |city|
										if (city == destin.getCity())
											destin.photos.each do |photo|
												dates.each do |date|
													if (date == photo.getDateTaken())
														picIsIn = false
														photos.each do |pic|
															if (pic == photo.getUrl())
																picIsIn = true
															end
														end
														if !picIsIn  && photo.getUrl().size() > 1
															photos.push(photo.getUrl())
														end
													end	
												end
											end
										end
									end
								end
							end
						end
					end
				end
			end
		end			
	end
	
	if(selInds[5] > photos.size())
		selInds[5] = 0
	end
	
	if(selInds[5] > 0)
		@journal.trips.each do |trip|
			trip.destinations.each do |destin|
				destin.photos.each do |photo|
					if ( @lists[5].getItem(selInds[5]).text == photo.getUrl())
						loadImage(photo.getUrl())
						@commentBox.text =  @journal.owner.getOwner + "\n" + trip.getName() + "\n" + destin.getName() + "\n" + destin.getCountry() + "\n" + destin.getCity() + "\n" + photo.getUrl() + "\n"	+ photo.getDateTaken() + "\n" + photo.getComment()
					end
				end
			end			
		end	
	end
	
	@lists[0].clearItems()
	@lists[1].clearItems()
	@lists[2].clearItems()
	@lists[3].clearItems()
	@lists[4].clearItems()
	@lists[5].clearItems()
	
	@lists[0].appendItem("All")
	@lists[1].appendItem("All")
	@lists[2].appendItem("All")
	@lists[3].appendItem("All")	
	@lists[4].appendItem("All")
	@lists[5].appendItem("None")
	
	trips.each do |tripName|
		@lists[0].appendItem(tripName)
	end
	
	destins.each do |destin|
		@lists[1].appendItem(destin)
	end
	
	countries.each do |conutry|
		@lists[2].appendItem(conutry)
	end
	
	cities.each do |city|
		@lists[3].appendItem(city)
	end
	
	dates.each do |date|
		@lists[4].appendItem(date)
	end
	
	photos.each do |pic|
		@lists[5].appendItem(pic)
	end
	
	@lists[0].setCurrentItem(selInds[0])
	@lists[1].setCurrentItem(selInds[1])
	@lists[2].setCurrentItem(selInds[2])
	@lists[3].setCurrentItem(selInds[3])
	@lists[4].setCurrentItem(selInds[4])
	@lists[5].setCurrentItem(selInds[5])
		
  end
  
  def hasExtension?(filename, ext)
    File.basename(filename, ext) != File.basename(filename)
  end
  
  def loadImage(file)
    img = nil
    if hasExtension?(file, ".gif")
      img = FXGIFImage.new(getApp(), nil, IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP)
    elsif hasExtension?(file, ".bmp")
      img = FXBMPImage.new(getApp(), nil, IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP)
    elsif hasExtension?(file, ".xpm")
      img = FXXPMImage.new(getApp(), nil, IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP)
    #elsif hasExtension?(file, ".png")
      #img = FXPNGImage.new(getApp(), nil, IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP)
    elsif hasExtension?(file, ".jpg")
      img = FXJPGImage.new(getApp(), nil, IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP)
    elsif hasExtension?(file, ".pcx")
      img = FXPCXImage.new(getApp(), nil, IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP)
    elsif hasExtension?(file, ".tif")
      img = FXTIFImage.new(getApp(), nil, IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP)
    elsif hasExtension?(file, ".tga")
      img = FXTGAImage.new(getApp(), nil, IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP)
    elsif hasExtension?(file, ".ico")
      img = FXICOImage.new(getApp(), nil, IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP)
    end

    if img.nil?
      FXMessageBox.error(self, MBOX_OK, "Error loading image",
        "Unsupported image type: #{file}")
      return
    end

    getApp().beginWaitCursor do
      FXFileStream.open(file, FXStreamLoad) { |stream| img.loadPixels(stream) }
      img.create
      @imageview.image = img
    end
  end
  
  def onCmdOpen(sender, sel, ptr)
    openDialog = FXFileDialog.new(self, "Open Image")
    openDialog.filename = @filename
    patterns = ["TravelJournal (*.xml)", "All Files (*)"]
    openDialog.patternList = patterns
    openDialog.currentPattern = @preferredFileFilter
    if openDialog.execute != 0
	  @filename = openDialog.filename
      loadJournal(@filename)
    end
	return 1
  end

  def onCmdSave(sender, sel, ptr)
    @journal.WriteToFile(@filename)
	return 1
  end
  
  def onCmdUpdate(sender, sel, ptr)
	uploader = Uploader.new("token")
	uploader.uploadJournal(@journal)
	@journal.WriteToFile(@filename)
	UploadDialog.new(self).execute
	return 1
  end
  
  def onCmdSel(sender, sel, ptr)
	setLists()
  end
  
  def onCmdQuit(sender, sel, ptr)
    getApp().reg().writeIntEntry("SETTINGS", "x", x)
    getApp().reg().writeIntEntry("SETTINGS", "y", y)
    getApp().reg().writeIntEntry("SETTINGS", "width", width)
    getApp().reg().writeIntEntry("SETTINGS", "height", height)
    getApp().exit(0)
  end
  
  def create
    xx = getApp().reg().readIntEntry("SETTINGS", "x", 0)
    yy = getApp().reg().readIntEntry("SETTINGS", "y", 0)
    ww = getApp().reg().readIntEntry("SETTINGS", "width", 850)
    hh = getApp().reg().readIntEntry("SETTINGS", "height", 600)
    position(xx, yy, ww, hh)
    super   
    show(PLACEMENT_SCREEN)
  end  
end

class UploadDialog < FXDialogBox

  def initialize(owner)
    super(owner, "Upload", DECOR_TITLE|DECOR_BORDER)
	horframe = FXHorizontalFrame.new(self, LAYOUT_SIDE_TOP | LAYOUT_FILL_X)
	FXLabel.new(horframe, "The journal has been uploaded to www.flick.com/something!!!", nil, LAYOUT_SIDE_TOP | JUSTIFY_LEFT)
	buttons = FXHorizontalFrame.new(self,
      LAYOUT_SIDE_BOTTOM|FRAME_NONE|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,
      :padLeft => 80, :padRight => 80, :padTop => 10, :padBottom => 5)
	accept = FXButton.new(buttons, "&Okie Dokie", nil, self, ID_ACCEPT,
      FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_X|LAYOUT_CENTER_Y)	
  end
end

if __FILE__ == $0
  application = FXApp.new("JournalViewer", "Flcikr")

  window = JournalWindow.new(application)

  application.addSignal("SIGINT", window.method(:onCmdQuit))

  application.create

  application.run
end
